#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "dllist.h"
#include "log.h"
#include "pollstat.h"
#include "snmpapi.h"

static int
EnumAllIfsDescrs(char szHostname[], char szCommunity[], PSNMP_VARIABLE *ppvar)
{
  char szRootOID[]="IF-MIB::ifDescr";

  return SNMP_Walk(szHostname, szCommunity, szRootOID, ppvar);
}

static void
GetInterfaceStatus(char szHostname[], char szCommunity[], INTERFACE *pif)
{
  PSNMP_VARIABLE pvar;
  char szOID[256];

  sprintf(szOID, "IF-MIB::ifOperStatus.%d", pif->nIndex);
  if(SNMP_Get(szHostname, szCommunity, szOID, &pvar)<0)
  {
    Logf(FRUNK_LOG_ERR,
         "Could not get interface status for %s@%s using community %s.",
         pif->pstrDescr, szHostname, szCommunity);
    return;
  }
  pif->timeLastPolled=time(NULL);
  pif->nLastOperStatus=pvar->value.integer;

  SNMP_FreeVars(pvar);
}

static int
GetIfIndexFromDescr(PSNMP_VARIABLE pvar, char szIfDescr[])
{
  while(pvar)
  {
    if(strcasecmp(pvar->value.string, szIfDescr)==0)
    {
      return atoi(strrchr(pvar->oid, '.')+1);
    }
    pvar=pvar->next;
  }
  return -1;
}

void
PollStatus(PCONFIG_DATA pcd)
{
  PDLLELEM pedev;

  pedev=DLL_GetHeadElem(&pcd->dllDevices);
  while(pedev)
  {
    PSNMP_VARIABLE pvar;
    PDLLELEM pdllElemIfs;
    PDEVICE pdev;

    pdev=DLL_GetNextElem(&pedev);
    if(EnumAllIfsDescrs(pdev->pstrAddress, pdev->pstrCommunity, &pvar)<0)
    {
      Logf(FRUNK_LOG_ERR, "Couldn't get interface descriptions for %s.",
           pdev->pstrAddress);
      continue;
    }
    pdllElemIfs=DLL_GetHeadElem(&pdev->dllInterfaces);
    while(pdllElemIfs)
    {
      PINTERFACE pif;

      pif=DLL_GetNextElem(&pdllElemIfs);
      pif->nIndex=GetIfIndexFromDescr(pvar, pif->pstrDescr);
      if(pif->nIndex>0)
      {
        GetInterfaceStatus(pdev->pstrAddress, pdev->pstrCommunity, pif);
      }
      else
      {
        Logf(FRUNK_LOG_ERR, "Could not get match interface description '%s' "
                      "on device '%s' using community '%s'",
             pif->pstrDescr, pdev->pstrAddress, pdev->pstrCommunity);
      }
    }
    SNMP_FreeVars(pvar);
  }
}

